#include "fault_iit.hpp"

using namespace motion;
///> 长延迟
bool fault_iit::CompareValue(bool isResume)
{
	uint8_t i, j;
	uint32_t max = 0;
	for(i = 0; i < ResourceValueLen; i++)
	{
		if(ResourceValue[i] > max)
		{
			max = ResourceValue[i];
		}
	}
	mReserver2 = max;
	if(isResume)
	{
		switch(FaultResumeCompareMethod)
		{
			case FAULT_COMPAREMETHOD_OR:
				for(i = 0; i < ResourceValueLen; i++)
				{
					if(ResourceValue[i] <= FaultResumeValue)
					{
						return(true);
					}
				}
				break;
			case FAULT_COMPAREMETHOD_AND:
				for(i = 0; i < ResourceValueLen; i++)
				{
					if(ResourceValue[i] > FaultResumeValue)
					{
						return(false);
					}
				}
				return(true);
			case FAULT_COMPAREMETHOD_BILATERAL:
				j = 0;
				for(i = 0; i < ResourceValueLen; i++)
				{
					if(ResourceValue[i] <= FaultResumeValue)
					{
						j++;
					}
				}
				if(j == ResourceValueLen || j == 0)
				{
					return(false);
				}
				return(true);
		}
	}
	else
	{
		switch(FaultTrigCompareMethod)
		{
			case FAULT_COMPAREMETHOD_OR:
				for(i = 0; i < ResourceValueLen; i++)
				{
					if(ResourceValue[i] >= FaultTrigValue)
					{
						if(!LimitEnable)
						{
							return(true);
						}
						if(ResourceValue[i] < LimitValue)
						{
							return(true);
						}
					}
				}
				break;
			case FAULT_COMPAREMETHOD_AND:
				for(i = 0; i < ResourceValueLen; i++)
				{
					if(ResourceValue[i] < FaultTrigValue)
					{
						return(false);
					}
					if(LimitEnable && ResourceValue[i] >= LimitValue)
					{
						return(false);
					}
				}
				return(true);
			case FAULT_COMPAREMETHOD_BILATERAL:
				j = 0;
				for(i = 0; i < ResourceValueLen; i++)
				{
					if(ResourceValue[i] >= FaultTrigValue)
					{
						if(!LimitEnable)
						{
							j++;
						}
						else if(ResourceValue[i] < LimitValue)
						{
							j++;
						}
					}
				}
				if(j == ResourceValueLen || j == 0)
				{
					return(false);
				}
				return(true);
		}
	}
	return(false);
}

void fault_iit::mTicked(void)
{
	if(WarningEnable)
	{
		if(FaultStatus == FAULT_STATUS_HAPPEND || FaultStatus == FAULT_STATUS_RESUME)
		{
			WarningStatus = true;
		}
		else
		{
			if(!CompareValue(false))
			{
				WarningStatus = false;
				mWarningCount = 0;
			}
			else if(mWarningCount < WarningTrigTime)
			{
				mWarningCount++;
				if(mWarningCount >= WarningTrigTime)
				{
					WarningStatus = true;
				}
			}
		}
	}
	else
	{
		WarningStatus = false;
	}
	if(!FaultEnable)
	{
		return;
	}
	switch(FaultStatus)
	{
		case FAULT_STATUS_NONE:
			if(CompareValue(false))
			{
				FaultStatus = FAULT_STATUS_HOLD;
			}
			if(mHeatAccumulationCount > Thermolysis)
			{
				mHeatAccumulationCount -= Thermolysis;
			}
			else
			{
				mHeatAccumulationCount = 0;
			}
			break;
		case FAULT_STATUS_HOLD:
			if(!CompareValue(false))
			{
				FaultStatus = FAULT_STATUS_NONE;
			}
			else if(mHeatAccumulationCount < HeatAccumulation)
			{
				mHeatAccumulationCount += mReserver2 * mReserver2;
				if(mHeatAccumulationCount >= HeatAccumulation)
				{
					FaultStatus = FAULT_STATUS_HAPPEND;
					uint8_t i;
					for(i = 0; i < ResourceValueLen; i++)
					{
						FreezValue[i] = ResourceValue[i];
					}
				}
			}
			break;
		case FAULT_STATUS_HAPPEND:
			if(CompareValue(true))
			{
				FaultStatus = FAULT_STATUS_RESUME;
			}
			break;
		case FAULT_STATUS_RESUME:
			if(!CompareValue(true))
			{
				FaultStatus = FAULT_STATUS_HAPPEND;
			}
			else if(mHeatAccumulationCount > Thermolysis)
			{
				mHeatAccumulationCount -= Thermolysis;
			}
			else
			{
				mHeatAccumulationCount = 0;
				FaultStatus = FAULT_STATUS_NONE;
			}
			break;
	}
}

fault_iit::fault_iit(void)
	:fault()
{
	mHeatAccumulationCount = 0;
	mReserver2 = 0;
}

fault_iit::~fault_iit(void)
{
	Unregister();
}

void fault_iit::Reset()
{
	fault::Reset();
	mHeatAccumulationCount = 0;
	mReserver2 = 0;
}
